//
//  Test6ViewController.m
//  JKNSURLConncetion
//
//  Created by 王冲 on 2019/1/22.
//  Copyright © 2019年 JK科技有限公司. All rights reserved.
//

#import "Test6ViewController.h"

/**
 NSURLConnectionDownloadDelegate ： 不要使用，它是专门针对杂志下载提供的接口
 如果使用它下载，可以监听到下载进度，但是找不到下载的文件
 Newsstand Kit’s downloadWithDelegate: 专门用来做杂志的Kit
 */
@interface Test6ViewController ()<NSURLConnectionDataDelegate>

@property(nonatomic,strong) UILabel *progressLabel;

/**
 要下载的文件总大小
 */
@property(nonatomic,assign) long long exceptedContentLength;

/**
 当前已经下载的文件总大小
 */
@property(nonatomic,assign) long long currentDownContentLength;

/**
 保存下载视频的路径
 */
@property(nonatomic,strong) NSString *downFilePath;

/* 保存文件的输出流
 - (void)open; 写入之前，打开流
 - (void)close; 写入完毕之后，关闭流
 */
@property(nonatomic,strong)NSOutputStream *fileStream;

/*
 保存下载线程的运行循环
 */

@property(nonatomic,assign)CFRunLoopRef downloadRunloop;

@end

@implementation Test6ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor purpleColor];
    
    [self.view addSubview: self.progressLabel];
}

-(UILabel *)progressLabel{
    
    if (!_progressLabel) {
        
        _progressLabel = [[UILabel alloc]initWithFrame:CGRectMake(20, 100, JK_SCREEN_WIDTH-40, 100)];
        _progressLabel.backgroundColor = [UIColor yellowColor];
        _progressLabel.textColor = [UIColor brownColor];
    }
    
    return _progressLabel;
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    // http://images.ciotimes.com/2ittt-zm.mp4
    
    //将网络操作放在异步线程，异步的运行循环默认不启动，没有办法监听接下来的网络事件
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        // 1、对视频链接进行编码
        // 在iOS程序中，访问一些HTTP/HTTPS的资源服务时，如果url中存在中文或者特殊字符时，会导致无法正常的访问到资源或服务，想要解决这个问题，需要对url进行编码。
        NSString *urlStr = @"http://images.ciotimes.com/2ittt-zm.mp4";
        
        // 在 iOS9 之后废弃了
        // urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        // iOS9 之后取代上面的 api
        urlStr = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
        
        // 2、string 转 NSURL
        NSURL *url = [NSURL URLWithString:urlStr];
        
        // 3、创建 NSURLRequest 对象
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        
        // 4、NSURLConnection 下载 视频
        /**
         By default, for the connection to work correctly, the calling thread’s run loop must be operating in the default run loop mode.
         为了保证链接工作正常，调用线程的RunLoop,必须在默认的运行循环模式下
         */
        NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
        
        // 设置代理工作的操作 [[NSOperationQueue alloc]init] 默认创建一个异步并发队列
        [connection setDelegateQueue:[[NSOperationQueue alloc]init]];
        
        [connection start];
        
        //5.启动运行循环
        /*
         CoreFoundation 框架 CFRunLoop
         CFRunloopStop() 停止指定的runloop
         CFRunloopGetCurrent() 获取当前的Runloop
         CFRunloopRun() 直接启动当前的运行循环
         */
        
        // (1)、拿到当前的运行循环
        self.downloadRunloop = CFRunLoopGetCurrent();
        // (2)、启动当前的运行循环
        CFRunLoopRun();
        
    });
    
    
    
    
}

// 1、接收服务器的响应 --- 状态和响应头做一些准备工作
// expectedContentLength : 文件的总大小
// suggestedFilename : 服务器建议保存的名字
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    
    // 记录文件的总大小
    self.exceptedContentLength = response.expectedContentLength;
    // 当前下载的文件大小初始化为 0
    self.currentDownContentLength = 0;
    
    // 创建下载的路径
    self.downFilePath = [@"/Users/wangchong/Desktop/JK视频下载器" stringByAppendingPathComponent:response.suggestedFilename];
    
    //删除 如果路径不存在时，就什么的不做！ 就文件存在是，就会直接删除
    [[NSFileManager defaultManager]removeItemAtPath:self.downFilePath error:nil];
    
    // 创建输出流
    self.fileStream = [[NSOutputStream alloc]initToFileAtPath:self.downFilePath append:YES];
    [self.fileStream open];
    
    
}

// 2、接收服务器的数据，由于数据是分块发送的，这个代理方法会被执行多次，因此我们也会拿到多个data
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    
    // JKLog(@"接收到的数据长度=%tu",data.length);
    self.currentDownContentLength += data.length;
    
    // 计算百分比
    // progress = (float)long long / long long
    float progress = (float)self.currentDownContentLength/self.exceptedContentLength;
    
    JKLog(@"下载的进度=%f",progress);
    
    //在主线程更新UI
    dispatch_async(dispatch_get_main_queue(), ^{
        
        self.progressLabel.text = [NSString stringWithFormat:@"下载进度：%f",progress];
    });
    
    // 将数据拼接起来，并判断是否可写如，一般情况下可写入，除非磁盘空间不足
    if ([self.fileStream hasSpaceAvailable]) {
        
        [self.fileStream write:data.bytes maxLength:data.length];
    }

}

// 3、接收到所有的数据加载完毕后会有一个通知
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    
    JKLog(@"下载完毕");
    [self.fileStream close];
    // 关闭当前下载完的 RunLoop
    CFRunLoopStop(self.downloadRunloop);
    
}

// 4、下载错误的处理
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
    
    JKLog(@"链接失败");
    
}




@end
